package com.cheng.controller;

import com.cheng.common.exception.CommonException;
import com.cheng.common.results.DataRslt;
import com.cheng.common.utils.CodeUtil;
import com.cheng.common.utils.IdUtil;
import com.cheng.common.utils.StringUtil;
import com.cheng.data.entity.ExceptionEntity;
import com.cheng.data.mapper.ExceptionMapper;
import com.cheng.data.vo.UserInfoVO;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UnknownAccountException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.ConversionFailedException;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import javax.naming.AuthenticationException;
import java.io.EOFException;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Date;

/**
 * @author: ChengJW
 * @date: 2021/11/1 22:36
 * @version: 1.0
 * @description: 统一异常处理类
 */
@RestControllerAdvice
public class ExceptionHelper {

    private final static Logger log = LoggerFactory.getLogger(ExceptionHelper.class);

    @Autowired
    private ExceptionMapper exceptionMapper;

    /**
    * @author: ChengJW
    * @params: [exception]
    * @return: com.cheng.common.results.DataRlst
    * @date: 2021/11/2
    * @description: 自定义异常处理
    */
    @ExceptionHandler(CommonException.class)
    public DataRslt commonExceptionHandler(CommonException exception) throws CommonException{
        log.error("出现异常,CommonExceptionHandler处理器正在处理:"+exception.getMsg(),exception);
        insertException(exception);
        return DataRslt.exception(CodeUtil.CODE_MAP.get(exception.getCode()));
    }

    /**
    * @author: ChengJW
    * @params: [exception]
    * @return: com.cheng.common.results.DataRlst
    * @date: 2021/11/2
    * @description: 其他异常处理
    */
    @ExceptionHandler(Exception.class)
    public DataRslt exceptionHandler(Exception exception){
        log.error("出现异常,ExceptionHandler处理器正在处理:"+exception.getMessage(),exception);
        CommonException ex = createCommonException(exception);
        insertException(ex);
        return DataRslt.exception();
    }

    /**
    * @author: ChengJW
    * @params: [exception]
    * @return: void
    * @date: 2021/11/2
    * @description: 往 exception 表里插入数据
    */
    public void insertException(Exception exception){

        String userName = null;
        String userCode = null;
        String userRealName = null;
        if (null != SecurityUtils.getSubject().getPrincipal()) {
            UserInfoVO userInfoVO = (UserInfoVO) SecurityUtils.getSubject().getPrincipal();
            userName = userInfoVO.getUrNm();
            //所属机关代码
            userCode = userInfoVO.getUrDwCode();
            userRealName = userInfoVO.getUrRealNm();

        }
        ExceptionEntity entity = new ExceptionEntity();
        entity.setExUserName(userName);
        entity.setExUserCode(userCode);
        entity.setExUserRealName(userRealName);
        CommonException commonException = (CommonException)exception;
        String msg = commonException.getMsg();
        if (msg != null && msg.length() > CodeUtil.EXCE_MSG_LENGTH){
            msg = StringUtil.subString(msg,0,CodeUtil.EXCE_MSG_LENGTH);
        }
        entity.setExId(IdUtil.getExceptionId());
        entity.setExMsg(msg);
        String desc = commonException.getDesc();
        if (desc != null && desc.length() > CodeUtil.EXCE_MSG_LENGTH){
            desc = StringUtil.subString(desc,0,CodeUtil.EXCE_MSG_LENGTH);
        }
        entity.setExDesc(desc);
        entity.setExClass(commonException.getClassName());
        entity.setExMethod(commonException.getMethodName());
        entity.setStDt(new Date());
        entity.setUtDt(new Date());
        exceptionMapper.insert(entity);
    }

    public CommonException createCommonException(Exception e){
        CommonException ex = new CommonException();
        StackTraceElement st = e.getStackTrace()[0];
        ex.setClassName(st.getClassName());
        ex.setMethodName(st.getMethodName());
        ex.setDesc(e.getMessage());
        if (e instanceof NullPointerException){
            // 空指针
            ex.setMsg(CodeUtil.CODE_MAP.get(CodeUtil.CJW03));
        }else if (e instanceof ClassNotFoundException){
            // 类不存在
            ex.setDesc(CodeUtil.CODE_MAP.get(CodeUtil.CJW04));
        }else if (e instanceof ArrayIndexOutOfBoundsException){
            // 数组下标越界
            ex.setMsg(CodeUtil.CODE_MAP.get(CodeUtil.CJW05));
        }else if (e instanceof NumberFormatException){
            // 字符串转换为数字异常
            ex.setMsg(CodeUtil.CODE_MAP.get(CodeUtil.CJW06));
        }else if (e instanceof IllegalAccessException){
            // 没有访问权限
            ex.setMsg(CodeUtil.CODE_MAP.get(CodeUtil.CJW07));
        }else if (e instanceof ArithmeticException){
            // 算术异常
            ex.setMsg(CodeUtil.CODE_MAP.get(CodeUtil.CJW08));
        }else if (e instanceof ClassCastException){
            // 强制类型转换异常
            ex.setMsg(CodeUtil.CODE_MAP.get(CodeUtil.CJW09));
        }else if (e instanceof NegativeArraySizeException){
            // 数组负下标异常
            ex.setMsg(CodeUtil.CODE_MAP.get(CodeUtil.CJW10));
        }else if (e instanceof EOFException){
            // 文件已结束异常
            ex.setMsg(CodeUtil.CODE_MAP.get(CodeUtil.CJW11));
        }else if (e instanceof FileNotFoundException){
            // 文件未找到异常
            ex.setMsg(CodeUtil.CODE_MAP.get(CodeUtil.CJW12));
        }else if (e instanceof SQLException){
            // 操作数据库异常
            ex.setMsg(CodeUtil.CODE_MAP.get(CodeUtil.CJW13));
        }else if (e instanceof IOException){
            // 输入输出异常
            ex.setMsg(CodeUtil.CODE_MAP.get(CodeUtil.CJW14));
        }else if (e instanceof NoSuchMethodException){
            // 方法未找到异常
            ex.setMsg(CodeUtil.CODE_MAP.get(CodeUtil.CJW15));
        }else if (e instanceof IllegalArgumentException){
            // 方法的参数错误
            ex.setMsg(CodeUtil.CODE_MAP.get(CodeUtil.CJW16));
        }else if (e instanceof UnknownAccountException){
            //登录账户不存在
            ex.setMsg(CodeUtil.CODE_MAP.get(CodeUtil.CJW31));
        }else if (e instanceof AuthenticationException){
            // shiro身份验证异常
            ex.setMsg(CodeUtil.CODE_MAP.get(CodeUtil.CJW22));
        }else if (e instanceof BadSqlGrammarException){
            // badSql异常
            ex.setMsg(CodeUtil.CODE_MAP.get(CodeUtil.CJW25));
        }else if (e instanceof ConversionFailedException){
            //参数转换异常
            ex.setMsg(CodeUtil.CODE_MAP.get(CodeUtil.CJW59));
        }else if (e instanceof MethodArgumentTypeMismatchException){
            //springMVC前后端方法参数类型不一致，并且框架默认无法转换
            ex.setMsg(CodeUtil.CODE_MAP.get(CodeUtil.CJW60));
        }
        else {
            ex.setMsg(e.getMessage());
        }
        return ex;
    }
}
